/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */
/* Copyright (C) 2012 Zongyou Yao. All rights reserved.     */

#ifndef TABLE_INCLUDED
#define TABLE_INCLUDED

/**
 * It is a checked runtime error to pass a null table_t or a null key to any
 * table function.
 */
typedef struct table_t *table_t;


/**
 * Creates, initializes, and returns a new empty table that can hold an arbitrary
 * number of key-value pairs. hint is an estimate of the number of such pairs 
 * expected. It is a checked runtime error for hint < 0. cmp and hash are functions
 * for comparing and hashing keys. For keys x and y, cmp(x, y) must return an int < 0,
 * = 0, or > 0 if x < y, x == y, or x > y. If cmp(x, y) returns zero, then hash(x) 
 * must equal hash(y). If cmp == null or hash == null, table_new uses a function
 * suitable for atom_t keys.
 * Exception mem_failed can be raised.
 */
table_t table_new(int hint, int cmp(const void *x, const void *y), unsigned hash(const void *key));

/**
 * Deallocates and clears *table. It is a checked runtime error for table or 
 * *table to be null.
 */
void table_free(table_t *table);

/**
 * Returns the number of key-value pairs in table.
 */
int table_length(table_t table);

/**
 *
 */
void * table_put(table_t table, const void *key, void *value);

/**
 * Returns the value associated with key in table, or null if table does not 
 * hold key.
 */
void *table_get(table_t table, const void *key);

/**
 *
 */
void *table_remove(table_t table, const void *key);

/**
 * Calls apply(key, &value, cl) for each key-value in table in an unspecified 
 * order. It is a checked runtime error for apply to change table.
 */
void table_map(table_t table, void apply(const void *key, void **value, void *cl), void *cl);

/**
 *
 */
void **table_toarray(table_t table, void *end);

#endif
